#include<gui.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<unistd.h>
#include<sys/sys.h>

#define MOUSE_CURSOR_DIR "/system/cursors"
#define BACKGROUND_IMAGE_NAME "/system/background/login.jpg"
#define PROGRAMS_DIR "/system/userapp/"
#define ICON_NAME "/system/icons/login.png"

#define WINLOGIN_BLOCK_W 320
#define WINLOGIN_BLOCK_H 240

#define WINLOGIN_ICON_W  64
#define WINLOGIN_ICON_H  64

gui_surface_t *winlogin_surface;
gui_surface_t *winlogin_block; 
gui_spirit_t *winlogin_win;

int window_width,window_height;

gui_spirit_t *login_state;
gui_spirit_t *accept_entry;
gui_spirit_t *pwd_entry;


static int winlogin_init();
static void winlogin_setup();
static void winlogin_widget();
bool login_btn_event(gui_spirit_t *spirit,void *arg);


void winlogin_launch(const char *path,char *arg)
{
    char *argv[3]={(char *)path,arg,NULL};
    if(!fork())
    {
        char *p=(char *)path;
        if(*p=='/'&&*(p+1))
        {
            char *p=strrchr(path,'/');
            if(p)
            {
                *p='\0';
                chdir((const char*)path);
                *p='/';
            }
        }
        dprintf("[winlogin] boot desktop enviroment,plese wait\n");
        exit(execv((const char *)path,argv));
    }
}

bool login_btn_event(gui_spirit_t *spirit,void *arg)
{
     char *name=gui_entry_get_text(GUI_ENTRY(accept_entry));
     char *pwd=gui_entry_get_text(GUI_ENTRY(pwd_entry));

    /*name[5]='\0';
    pwd[5]='\0';*/

    if(strlen(name)<1)
        return true;

    dprintf("[winlogin] name %s pwd %s\n",name,pwd);

    if(!login(name,pwd))
    {
        gui_label_set_text(login_state,"Login Success",strlen("Login Success"));

        gui_button_set_disable(GUI_BUTTON(spirit));

        //hidden login window
        gui_spirit_hide(winlogin_win);

        winlogin_launch(PROGRAMS_DIR"desktop",NULL);
    }
    else
    {

        gui_label_set_text(login_state,"Login Failed",strlen("Login Failed"));
        //clear input
        gui_entry_set_text(login_state,"");
    }
    return true;
}

static int winlogin_init()
{
    winlogin_win=NULL;
    if(gui_init(NULL,NULL)<0)
    {
        printf("winlogin: gui_init error!\n");
        return -1;
    }
    gui_spirit_t *spirit=gui_window_create(GUI_WINDOW_POPUP);
    if(!spirit)
    {
        printf("[winlogin] gui_create winlog window error\n");
        return -1;
    }
    gui_window_set_fixed(GUI_WINDOW(spirit),true);
    assert(!gui_window_resize_to_screen(GUI_WINDOW(spirit)));
    gui_window_set_resizeable(GUI_WINDOW(spirit),false);
    gui_window_get_screen(GUI_WINDOW(spirit),&window_width,&window_height);
    winlogin_surface=gui_window_get_surface(GUI_WINDOW(spirit));
    gui_spirit_show(spirit);
    winlogin_win=spirit;
    return 0;
}

int winlogin_load_background(const char *path)
{
    gui_image_t *img=gui_image_load(BACKGROUND_IMAGE_NAME);
    if(!img)
        return -1;
    gui_surface_t *surface=gui_window_get_surface(GUI_WINDOW(winlogin_win));
    if(!surface)
        return -1;
    gui_surface_t img_surface;
    gui_surface_init(&img_surface,img->w,img->h,(uint32_t*)img->buff);
    gui_surface_blit_scaled(&img_surface,NULL,surface,NULL);
    gui_window_flip(GUI_WINDOW(winlogin_win));
    gui_image_destroy(img);
    return 0;
}

static void winlogin_setup()
{
    //load mouse cursor 
    gui_window_load_mouse_cursor(GUI_WINDOW(winlogin_win),MOUSE_CURSOR_DIR);
    //load background
    winlogin_load_background(BACKGROUND_IMAGE_NAME);
    //load widget
    winlogin_widget();
}

int winlogin_load_icon(const char *path,int x,int y)
{
    gui_image_t *img=gui_image_load2((char*)path,WINLOGIN_ICON_W,WINLOGIN_ICON_H);
    if(!img)
        return -1;
    gui_surface_t img_surface;
    gui_surface_init(&img_surface,img->w,img->h,(uint32_t*)img->buff);
    gui_rect_t dstrect={x,y,img->w,img->h};
    gui_surface_blit(&img_surface,NULL,winlogin_surface,&dstrect);
    gui_image_destroy(img);
    return 0;
}

static void winlogin_widget()
{
    winlogin_block=gui_surface_create(WINLOGIN_BLOCK_W,WINLOGIN_BLOCK_H);
    assert(winlogin_block);
    gui_surface_rectfill(winlogin_block,0,0,winlogin_block->w,winlogin_block->h,GUI_RGB(240,240,240));
    gui_surface_rect(winlogin_block,0,0,winlogin_block->w,winlogin_block->h,GUI_RGB(228,228,228));

    //set background color
    winlogin_win->style.background_color=GUI_RGB(240,240,240);

    //input box
    accept_entry=gui_entry_create();
    assert(accept_entry);
    assert(!gui_container_add(GUI_CONTAINER(winlogin_win),accept_entry));
    gui_spirit_reset_size(accept_entry,180,accept_entry->height);

    pwd_entry=gui_entry_create();
    assert(pwd_entry);
    assert(!gui_container_add(GUI_CONTAINER(winlogin_win),pwd_entry));
    gui_spirit_reset_size(pwd_entry,180,pwd_entry->height);

    //input box name
    gui_spirit_t *accept_label=gui_label_create("account");
    assert(accept_label);
    assert(!gui_container_add(GUI_CONTAINER(winlogin_win),accept_label));
    accept_label->style.background_color=GUI_COLOR_NONE;

    gui_spirit_t *pwd_label=gui_label_create("password");
    assert(pwd_label);
    assert(!gui_container_add(GUI_CONTAINER(winlogin_win),pwd_label));
    pwd_label->style.background_color=GUI_COLOR_NONE;

    login_state=gui_label_create("wait login");
    assert(login_state);
    assert(!gui_container_add(GUI_CONTAINER(winlogin_win),login_state));
    login_state->style.background_color=GUI_COLOR_NONE;

    gui_spirit_t *login_btn=gui_button_create_with_label("Login");
    assert(login_btn);
    assert(!gui_container_add(GUI_CONTAINER(winlogin_win),login_btn));
    gui_spirit_reset_size(login_btn,80,login_btn->height);
    gui_signal_connect(login_btn,"button_press",login_btn_event,NULL);


    //redirect
    int center_x=window_width/2;
    int center_y=window_height/2;

    int block_x=center_x-winlogin_block->w/2;
    int block_y=center_y-winlogin_block->h/2;

    int label_x=block_x+30;
    int label_y=block_y+110;

    int entry_x=label_x+80;
    int entry_y=label_y;

    int btn_x=entry_x+100;
    int btn_y=entry_y+30+50;

    int login_state_x=label_x;
    int login_state_y=btn_y;

    gui_spirit_set_pos(accept_label,label_x,label_y);
    gui_spirit_set_pos(pwd_label,label_x,label_y+30);
    gui_spirit_set_pos(accept_entry,entry_x,entry_y);
    gui_spirit_set_pos(pwd_entry,entry_x,entry_y+30);
    gui_spirit_set_pos(login_btn,btn_x,btn_y);
    gui_spirit_set_pos(login_state,login_state_x,login_state_y);


    //show spirit
    gui_rect_t dstrect={block_x,block_y,winlogin_block->w,winlogin_block->h};
    gui_surface_blit(winlogin_block,NULL,winlogin_surface,&dstrect);

    winlogin_load_icon(ICON_NAME,block_x,block_y+20);
    gui_window_flip(GUI_WINDOW(winlogin_win));

    gui_spirit_show(accept_entry);
    gui_spirit_show(pwd_entry);
    gui_spirit_show(accept_label);
    gui_spirit_show(pwd_label);
    gui_spirit_show(login_btn);
    gui_spirit_show(login_state);
}   

int main(int argc,char *argv[])
{
    if(winlogin_init()<0)
    {
        printf("[winlogin] init error!\n");
        return -1;
    }
    winlogin_setup();

    
    gui_main();
    return 0;
}
